package DAO;

import java.util.Vector;

import BUS.QueryProccessor;
import DTO.ColInfoDTO;
import DTO.ConstraintDTO;
import DTO.RecordDTO;
import DTO.TableDTO;



public class RecordDAO {
	private String _DatabasePath;

	public RecordDAO(String databasePath)
	{
		_DatabasePath = databasePath;
	}
	
	public Vector<RecordDTO> getAllRecord(String tableName) throws Exception
	{
		TableDAO tbDAO = new TableDAO(_DatabasePath);
		TableDTO tbDTO = tbDAO.getTable(tableName);
		return tbDTO.get_recordList();
	}
	
	public void insertRecord(String tableName, RecordDTO recordDTO) throws Exception
	{
		TableDAO tbDAO = new TableDAO(_DatabasePath);
		TableDTO tbDTO = tbDAO.getTable(tableName);
		Vector<RecordDTO> recordList = tbDTO.get_recordList();
		int nCols = tbDTO.get_colInfoList().size();
//		if(nCols != recordDTO.get_data().length)
//			throw new Exception("Invalid data");
		Vector<ColInfoDTO> colInfoList = tbDTO.get_colInfoList();
		for(int i=0; i<colInfoList.size(); i++)//kiem tra tung cot du lieu
		{
			String dataType = colInfoList.elementAt(i).get_dataType();
			//kiem tra constraint
			ConstraintDTO constraint = colInfoList.elementAt(i).get_constraint();
			if(constraint.get_isNotNull() && recordDTO.get_data(i) == null)
				throw new Exception("Field " + (i+1) + " must be not null");
			if(constraint.get_isPrimaryKey())
			{
				Vector<RecordDTO> allRecords = tbDTO.get_recordList();
				for(int j=0; j<allRecords.size(); j++)
				{
					String data = allRecords.elementAt(j).get_data(i);//du lieu cot hien tai
					if(QueryProccessor.compare(data, recordDTO.get_data(i), dataType, "="))
						throw new Exception("Field " + (i+1) + " must be unique");
				}
				if(recordDTO.get_data(i) == null)
					throw new Exception("Field " + (i+1) + " must be not null");
			}
			//kiem tra data type
			if(dataType.equalsIgnoreCase("STRING") && !QueryProccessor.isString(recordDTO.get_data(i)))
				throw new Exception("Invalid string data: " + recordDTO.get_data(i));
			if(dataType.equalsIgnoreCase("FLOAT") && !QueryProccessor.isFloat(recordDTO.get_data(i)))
				throw new Exception("Invalid float data: " + recordDTO.get_data(i));
		}
		tbDAO.removeTable(tableName);
		recordDTO.set_nCol(nCols);
		for(int i=0; i<recordDTO.get_data().length; i++)
		{
			String data = recordDTO.get_data()[i];
			if(data != null)
				recordDTO.get_data()[i] = data.replace("'", "");
			else
				recordDTO.get_data()[i] = null;
		}
		recordList.add(recordDTO);
		tbDTO.set_recordList(recordList);
		tbDAO.addTable(tbDTO);
	}
	
	public void deleteRecord(String tableName, RecordDTO recordDTO) throws Exception
	{
		TableDAO tbDAO = new TableDAO(_DatabasePath);
		TableDTO tbDTO = tbDAO.getTable(tableName);
		tbDAO.removeTable(tableName);
		Vector<RecordDTO> recordList = tbDTO.get_recordList();
		for(int i=0; i<recordList.size(); i++)
		{
			RecordDTO record = recordList.elementAt(i);
			Boolean comparedResult = true;
			for(int j=0; j<record.get_data().length; j++)
			{
				if(record.get_data()[j] == null)
				{
					if(recordDTO.get_data()[j] != null)
					{
						comparedResult = false;
						break;
					}
				}
				else{
					if(!record.get_data()[j].equals(recordDTO.get_data()[j]))
					{
						comparedResult = false;
						break;
					}	
				}
			}
			if(comparedResult)
				recordList.remove(i);
		}
				
		tbDTO.set_recordList(recordList);
		tbDAO.addTable(tbDTO);
	}
	
	public void updateRecord(String tableName, RecordDTO oldRecord, RecordDTO newRecord) throws Exception
	{
		deleteRecord(tableName, oldRecord);
		try{
			insertRecord(tableName, newRecord);
		}catch (Exception e) {
			// TODO: handle exception
			insertRecord(tableName, oldRecord);
			throw e;
		}
	}
}
